﻿#include "serialport.h"

#include <QDebug>

namespace Common {

	SerialPort::SerialPort(QObject *parent)
		: QObject(parent)
		, m_serialPort(new QSerialPort(this))
	{
		connect(m_serialPort, &QSerialPort::errorOccurred, this, &SerialPort::slotReceiveErrorOccurred);
	}

	SerialPort::~SerialPort()
	{
		if (m_serialPort != nullptr)
		{
			this->close();
			delete  m_serialPort;
			m_serialPort = nullptr;
		}
	}

	QSerialPort *SerialPort::getSerialPort()
	{
		return m_serialPort;
	}

	bool SerialPort::open(const QString portName,
		const QSerialPort::BaudRate baudRate,
		const QSerialPort::DataBits dataBits,
		const QSerialPort::Parity parity, 
		const QSerialPort::StopBits stopBits,
		const QSerialPort::FlowControl flowControl)
	{
		if (isOpen())
		{
			m_serialPort->clear();
			m_serialPort->close();
		}

		m_serialPort->setPortName(portName);
		m_serialPort->setBaudRate(baudRate);
		m_serialPort->setDataBits(dataBits);
		m_serialPort->setParity(parity);
		m_serialPort->setStopBits(stopBits);
		m_serialPort->setFlowControl(flowControl);
		m_serialPort->open(QIODevice::ReadWrite);

		return m_serialPort->isOpen();
	}

	void SerialPort::close()
	{
		if (m_serialPort->isOpen())
		{
			m_serialPort->clear();
			m_serialPort->close();
		}
	}

	bool SerialPort::isOpen()
	{
		return m_serialPort->isOpen();
	}

	bool SerialPort::clear()
	{
		return m_serialPort->clear();
	}

	bool SerialPort::sendSerialMsg(const QByteArray buff)
	{
		if (!isOpen())
		{
			return false;
		}

		m_serialPort->clear();
		m_serialPort->write(buff);
		return m_serialPort->flush();
	}

	bool SerialPort::recvSerialMsg(QByteArray & buff, const int replyTime)
	{
		if (!isOpen())
		{
			return false;
		}

		if (m_serialPort->waitForReadyRead(replyTime))
		{
			if (m_serialPort->bytesAvailable())
			{
				buff = m_serialPort->readAll();
				return true;
			}
		}
		return false;
	}

	bool SerialPort::sendAndReceiveSerialMsg(const QByteArray sendMsg, QByteArray &recvMsg, const int replyTime)
	{
		if (!isOpen())
		{
			return false;
		}

		if (sendSerialMsg(sendMsg))
		{
			bool ret = recvSerialMsg(recvMsg, replyTime);
			return ret;
		}
		return false;
	}

	void SerialPort::slotReceiveErrorOccurred(QSerialPort::SerialPortError error)
	{
		QString ERRORString;
		switch (error)
		{
		case QSerialPort::NoError:					//没有错误。
			ERRORString = "No Error";
			break;
		case QSerialPort::DeviceNotFoundError:		//找不到设备。
			ERRORString = "Device Not Found";
			break;									
		case QSerialPort::PermissionError:			//没有足够的权限。
			ERRORString = "Permission Denied";		
			break;									
		case QSerialPort::OpenError:				//打开设备时出错。
			ERRORString = "Open Error";				
			break;									
		case QSerialPort::ParityError:				//奇偶校验错误。
			ERRORString = "Parity Error";			
			break;									
		case QSerialPort::FramingError:				//帧错误。
			ERRORString = "Framing Error";			
			break;									
		case QSerialPort::BreakConditionError:		//断线条件错误。
			ERRORString = "Break Condition";		
			break;									
		case QSerialPort::WriteError:				//写数据时出错。
			ERRORString = "Write Error";			
			break;									
		case QSerialPort::ReadError:				//读数据时出错。
			ERRORString = "Read Error";				
			break;									
		case QSerialPort::ResourceError:			//设备被意外移除或系统资源不足。
			ERRORString = "Resource Error";
			break;
		case QSerialPort::UnsupportedOperationError:    //不支持的操作。
			ERRORString = "Unsupported Operation";
			break;
		case QSerialPort::UnknownError:             //未知错误。
			ERRORString = "Unknown Error";
			break;
		case QSerialPort::TimeoutError:             //操作超时。
			ERRORString = "Timeout Error";
			break;
		case QSerialPort::NotOpenError:             //尝试操作一个未打开的设备。
			ERRORString = "Not Open Error";
			break;
		default:
			ERRORString = "Other Error";
		}
		qDebug() << "SerialPortWorker::errorOccurred  ,info is  " << ERRORString;
	}

} //namespace Common
